package com.google.code.tretris;

import java.util.List;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.Window;
import android.view.WindowManager;

import com.google.code.tretris.common.WKC;
import com.google.code.tretris.debug.TextClientActivity;
import com.google.code.tretris.events.IPCClient;
import com.google.code.tretris.events.MoveEvent;
import com.google.code.tretris.events.UpdateBoardEvent;
import com.google.code.tretris.rendering.TretrisView;
import com.google.code.tretris.server.GamePlayService;
import com.google.code.tretris.server.TretrisServer;

public class Tretris extends Activity implements TretrisView.MovementListener {
	private static final String LOG_TAG = Tretris.class.getName();
	private ServiceConnection serviceConnection;
	private TretrisServer serviceInstance = null;
	private TretrisView view;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);

		view = new TretrisView(this);
		setContentView(view);
	}

	@Override
	protected void onPause() {
		if (serviceInstance != null) {
			try {
				serviceInstance.unregisterClient(WKC.GRAPHICAL_CLIENT_IPC_UID,
						callback);
			} catch (RemoteException e) {
				Log.e(LOG_TAG, "Unable to unregister client", e);
			}
		}
		unbindService(serviceConnection);
		serviceInstance = null;
		serviceConnection = null;
		super.onPause();
	}

	@Override
	protected void onResume() {

		// Bind to the tretris service. Probably shouldn't do this here
		serviceConnection = new ServiceConnection() {
			public void onServiceDisconnected(ComponentName name) {
				Log.d(LOG_TAG, "Service disconnected: "
						+ name.flattenToString());
				serviceInstance = null;
			}

			public void onServiceConnected(ComponentName name, IBinder service) {
				Log.d(LOG_TAG, "Service connected: " + name.flattenToString());
				serviceInstance = TretrisServer.Stub.asInterface(service);
				try {
					// Register our callback on the service (currently this is
					// buggy and registers the same client several times if the
					// activity is recreated)
					serviceInstance.registerClient(
							WKC.GRAPHICAL_CLIENT_IPC_UID, callback);
					serviceInstance.startPlay();

				} catch (RemoteException e) {
					Log.e(LOG_TAG, "Unable to add client to the service", e);
				}
			}
		};
		Intent serviceIntent = new Intent(this, GamePlayService.class);
		boolean boundToService = bindService(serviceIntent, serviceConnection,
				Context.BIND_AUTO_CREATE);
		Log.d(LOG_TAG, "Bound to service: " + boundToService);
		super.onResume();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
	}

	// Callback from the service ends up here.
	private IPCClient.Stub callback = new IPCClient.Stub() {

		public void update(final List<UpdateBoardEvent> events)
				throws RemoteException {
			view.onGameUpdate(events);
		}

		public void gameOver() throws RemoteException {
			Log.v(LOG_TAG, "Game over");
			view.onGameOver();
		}
	};

	public void onMovement(MoveEvent moveEvent) {

		try {
			serviceInstance.sendMovement(moveEvent);
		} catch (RemoteException e) {
			Log.e(LOG_TAG, "Unable to send movement", e);
		}
		
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater menuInflater = getMenuInflater();
		menuInflater.inflate(R.menu.gamemenu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.settingsmenuitem: {
			SettingsDialog settingsDialog = new SettingsDialog(this);
			settingsDialog.show();
			break;
		}
		case R.id.serverconsolemenuitem: {
			Intent intent = new Intent(this, ServerConsoleActivity.class);
			startActivity(intent);
			break;
		}
		case R.id.textclientmenuitem: {
			startActivity(new Intent(this, TextClientActivity.class));
			break;
		}
		}
		return super.onOptionsItemSelected(item);
	}

}